﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;

namespace Windows8Accelerator.Core.Xaml.Storage
{
    public class StorageHelper : StorageHelperBase
    {
        private static IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication();

        public static IsolatedStorageFileStream OpenLocalFile(string name)
        {
            if (!ISF.FileExists(name))
                return null;
            return ISF.OpenFile(name, FileMode.Open, FileAccess.Read);
        }
        
        public static async Task<StorageFolder> GetStorageFolderAsync(string name, StorageLocation location)
        {
            StorageFolder folder = null;
            switch (location)
            {
                case StorageLocation.Local:
                    folder = ApplicationData.Current.LocalFolder;
                    break;
                case StorageLocation.Roaming:
                    folder = ApplicationData.Current.RoamingFolder;
                    break;
                case StorageLocation.Temp:
                    folder = ApplicationData.Current.TemporaryFolder;
                    break;
                case StorageLocation.InstalledLocation:
                    folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
                    break;
                case StorageLocation.Path:
                    folder = await StorageFolder.GetFolderFromPathAsync(Path.GetDirectoryName(name));
                    break;
            }
            if (name != null && location != StorageLocation.Path)
            {
                var folderNames = Path.GetDirectoryName(name).Split(new char[] { '\\', '/' }, StringSplitOptions.RemoveEmptyEntries);
                foreach (var folderName in folderNames)
                {
                    folder = await folder.CreateFolderAsync(folderName, CreationCollisionOption.OpenIfExists);
                }
            }
            return folder;
        }

        public override async Task<FileInfo[]> GetFilesAsync(string directory, StorageLocation storageLocation)
        {
            var folder = await GetStorageFolderAsync(directory, storageLocation);
            var files = await folder.GetFilesAsync();
            return files.Select(
                (f) => new FileInfo() {
                    Path = f.Path,
                    Name = f.Name,
                    DateCreated = f.DateCreated,
                }
                ).ToArray();
        }

        public override async Task DeleteFilesAsync(string filePath, StorageLocation location)
        {
            var folder = await GetStorageFolderAsync(filePath, location);
            var file = await folder.GetFileAsync(Path.GetFileName(filePath));
            await file.DeleteAsync();
        }

        public override async Task CreateFileAsync(string filePath, StorageLocation location)
        {
            var folder = await GetStorageFolderAsync(filePath, location);
            await folder.CreateFileAsync(Path.GetFileName(filePath), CreationCollisionOption.ReplaceExisting);
        }

        public override async Task<Stream> OpenFileWriteAsync(string filePath, StorageLocation location, bool createIfNecessary = false)
        {
            var folder = await GetStorageFolderAsync(filePath, location);
            StorageFile file = null;
            try
            {
                file = await folder.GetFileAsync(Path.GetFileName(filePath));
            }
            catch { }
            if (file == null && createIfNecessary)
            {
                file = await folder.CreateFileAsync(Path.GetFileName(filePath), CreationCollisionOption.ReplaceExisting);
            }
            if (file == null)
                throw new FileNotFoundException(filePath, filePath);

            return await file.OpenStreamForWriteAsync();
        }

        public override async Task<Stream> OpenFileReadAsync(string filePath, StorageLocation location)
        {
            var folder = await GetStorageFolderAsync(filePath, location);
            var file = await folder.GetFileAsync(Path.GetFileName(filePath));
            return await file.OpenStreamForReadAsync();
        }
    }
}
